One great application of R is graphics. With some skill, one can generate whatever visualisation they please. Of course, this takes quite some practice and experimentation. Still, it is possible to make nice plots even without years of experience onder ones belt. There are basically two main approaches for making graphics: base-R and ggplot (the tidyverse).



1 Base-R graphics

1.1 Plot data.frame

When thinking about what to visualise, plotting your entire data (given that it is in the form of a data.frame) can be usefull, unless the data is large and contains many variables.

# Load data on New York Air Quality Measurements:
data(airquality)

# Plot data.frame:
plot(airquality,panel = panel.smooth,cex = 0.2)



1.2 Single plots

Make a scatter plot with two variables only:

# Plot tree hight against tree age:
plot(x = airquality$Temp,y = airquality$Wind,
     xlab='Temperature (°F)',
     ylab='Wind speed (mph)',
     pch=21,bg='gray80',
     main='Scatterplot')

Plot a frequency distribution (i.e., a histogram):

hist(rpois(1000,10),15,main='Histogram',xlab='Value',col='wheat')

Make a boxplot of chick weight as a function of feed:

data(chickwts)

# Specify custom colors:
cols = c("#999999", "#E69F00", "#56B4E9", 
         "#009E73", "#F0E442", "#0072B2")

# Draw plot:
boxplot(weight~feed,data = chickwts,
        ylab = 'Chick weight',xlab = 'Feed',
        col = cols)

  • Do it yourself! Make a horizontal barplot of the weight of chicks fed on horsebean, ordered along increasing weight. Also, make the bars of different color and adjust the spacing between columns to 0.5.

# your code comes here:



1.3 Combining different plots to same figure

Some times it might be desirable to present several plots side by side. While there are several approaches for achieving this in base R, we will here use the simples alternative. This is done by altering figure parameters:

# Plot two figures beside each other:
par(mfrow = c(1,2)) # change figure parameters

# left plot:
plot(airquality$Solar.R,airquality$Ozone,
     xlab='Solar radiation',ylab='Ozone (ppb)',
     pch=21,bg='dodgerblue',main='Scatterplot')

# right plot:
hist(airquality$Temp,
     main='Histogram',xlab='Temperature (°F)',col='wheat')




2 Visualising with ggplot

Especially if your not into elaborate programming of graphical layout, a good option is to turn to ggplot. With ggplot, one can make fairly good looking graphs with minimal effort.

# Load ggplot:
require(ggplot2)

# Get example data:
data(Orange)

# Plot:
p = ggplot(Orange, aes(age,circumference)) + geom_jitter()
p

So far so good. However, the plot does not look too impressive. As we have saveed the plot to object p, we can continue adding new layers to that object, just like in a graphical editor:

p + geom_smooth() + theme_minimal()

This looks much better already.

We could also add some eye-candy according to a grouping factor in the data:

p = ggplot(Orange, aes(age,circumference,col=Tree)) + 
      geom_jitter() + 
      geom_smooth(se=F) +
      theme_minimal() +
      xlab('Tree age (days)') + 
      ylab('Circumfenrence at chest hight (mm)')
p

  • Do it yourself! Make a horizontal boxplot of chick weight according to feed in ggplot. Make sore that the boxes are filled with different color depending on feed type.
# your code comes here:

3 Using Plotly

While ggplot is great, it generates static graphs, just like base-R. If one desires to add interactive components to figures, one can use either ggviz (an implementation of an interactive grammar of graphics, taking the best parts of ggplot, combining them with the reactive framework of shiny and drawing web graphics using vega) or plotly

The easiest way to use plotly is to convert an exaisting ggplot visualisation to plotly:

library(plotly)

ggplotly(p)

Building plotly graphs from scratch:

p2 = plot_ly(mtcars, x = ~disp, y = ~mpg)
p2 = add_markers(p2, color = ~factor(cyl), size = ~gear)
p2
LS0tCnRpdGxlOiAoNSkgR3JhcGhpY3MKYXV0aG9yOiAiTGFzc2UgUnVva29sYWluZW4sIEJpbG90IENvbnN1bHRpbmcgT3kiCm91dHB1dDoKICBodG1sX25vdGVib29rOgogICAgdG9jOiB5ZXMKICAgIHRvY19mbG9hdDogeWVzCiAgICBjb2xsYXBzZWQ6IGZhbHNlCiAgICB0aGVtZTogdW5pdGVkCiAgICBudW1iZXJfc2VjdGlvbnM6IHRydWUKICAgIGRmX3ByaW50OiBwYWdlZAotLS0KCjxpbWcgc3JjPSJjcm9wcGVkLXJzdHVkaW8gY29weS5wbmciIApzdHlsZT0icG9zaXRpb246YWJzb2x1dGU7dG9wOjVweDtyaWdodDozMHB4OyIgLz4KCi0tLQoKPGJyPjxicj4KCjxwIHN0eWxlPSd0ZXh0LWFsaWduOiBqdXN0aWZ5Oyc+T25lIGdyZWF0IGFwcGxpY2F0aW9uIG9mICoqUioqIGlzIGdyYXBoaWNzLiBXaXRoIHNvbWUgc2tpbGwsIG9uZSBjYW4gZ2VuZXJhdGUgd2hhdGV2ZXIgdmlzdWFsaXNhdGlvbiB0aGV5IHBsZWFzZS4gT2YgY291cnNlLCB0aGlzIHRha2VzIHF1aXRlIHNvbWUgcHJhY3RpY2UgYW5kIGV4cGVyaW1lbnRhdGlvbi4gU3RpbGwsIGl0IGlzIHBvc3NpYmxlIHRvIG1ha2UgbmljZSBwbG90cyBldmVuIHdpdGhvdXQgeWVhcnMgb2YgZXhwZXJpZW5jZSBvbmRlciBvbmVzIGJlbHQuIFRoZXJlIGFyZSBiYXNpY2FsbHkgdHdvIG1haW4gYXBwcm9hY2hlcyBmb3IgbWFraW5nIGdyYXBoaWNzOiBiYXNlLSoqUioqIGFuZCBgZ2dwbG90YCAodGhlIFtgdGlkeXZlcnNlYF0oaHR0cHM6Ly93d3cudGlkeXZlcnNlLm9yZy8pKS4gPHA+CgotLS0KCjxicj4KCiMgQmFzZS0qKlIqKiBncmFwaGljcwojIyAqUGxvdCBkYXRhLmZyYW1lKgpXaGVuIHRoaW5raW5nIGFib3V0IHdoYXQgdG8gdmlzdWFsaXNlLCBwbG90dGluZyB5b3VyIGVudGlyZSBkYXRhIChnaXZlbiB0aGF0IGl0IGlzIGluIHRoZSBmb3JtIG9mIGEgZGF0YS5mcmFtZSkgY2FuIGJlIHVzZWZ1bGwsIHVubGVzcyB0aGUgZGF0YSBpcyBsYXJnZSBhbmQgY29udGFpbnMgbWFueSB2YXJpYWJsZXMuCmBgYHtyLCBmaWcud2lkdGg9NCwgZmlnLmhlaWdodD00fQojIExvYWQgZGF0YSBvbiBOZXcgWW9yayBBaXIgUXVhbGl0eSBNZWFzdXJlbWVudHM6CmRhdGEoYWlycXVhbGl0eSkKCiMgUGxvdCBkYXRhLmZyYW1lOgpwbG90KGFpcnF1YWxpdHkscGFuZWwgPSBwYW5lbC5zbW9vdGgsY2V4ID0gMC4yKQpgYGAKCjxicj48YnI+CgojIyAqU2luZ2xlIHBsb3RzKgpNYWtlIGEgc2NhdHRlciBwbG90IHdpdGggdHdvIHZhcmlhYmxlcyBvbmx5OgpgYGB7cn0KIyBQbG90IHRyZWUgaGlnaHQgYWdhaW5zdCB0cmVlIGFnZToKcGxvdCh4ID0gYWlycXVhbGl0eSRUZW1wLHkgPSBhaXJxdWFsaXR5JFdpbmQsCiAgICAgeGxhYj0nVGVtcGVyYXR1cmUgKMKwRiknLAogICAgIHlsYWI9J1dpbmQgc3BlZWQgKG1waCknLAogICAgIHBjaD0yMSxiZz0nZ3JheTgwJywKICAgICBtYWluPSdTY2F0dGVycGxvdCcpCmBgYAoKUGxvdCBhIGZyZXF1ZW5jeSBkaXN0cmlidXRpb24gKGkuZS4sIGEgaGlzdG9ncmFtKToKYGBge3J9Cmhpc3QocnBvaXMoMTAwMCwxMCksMTUsbWFpbj0nSGlzdG9ncmFtJyx4bGFiPSdWYWx1ZScsY29sPSd3aGVhdCcpCmBgYAoKTWFrZSBhIGJveHBsb3Qgb2YgY2hpY2sgd2VpZ2h0IGFzIGEgZnVuY3Rpb24gb2YgZmVlZDoKYGBge3J9CmRhdGEoY2hpY2t3dHMpCgojIFNwZWNpZnkgY3VzdG9tIGNvbG9yczoKY29scyA9IGMoIiM5OTk5OTkiLCAiI0U2OUYwMCIsICIjNTZCNEU5IiwgCiAgICAgICAgICIjMDA5RTczIiwgIiNGMEU0NDIiLCAiIzAwNzJCMiIpCgojIERyYXcgcGxvdDoKYm94cGxvdCh3ZWlnaHR+ZmVlZCxkYXRhID0gY2hpY2t3dHMsCiAgICAgICAgeWxhYiA9ICdDaGljayB3ZWlnaHQnLHhsYWIgPSAnRmVlZCcsCiAgICAgICAgY29sID0gY29scykKYGBgCgotIDxwIHN0eWxlPSd0ZXh0LWFsaWduOiBqdXN0aWZ5Oyc+KipEbyBpdCB5b3Vyc2VsZiEqKiBNYWtlIGEgaG9yaXpvbnRhbCBiYXJwbG90IG9mIHRoZSB3ZWlnaHQgb2YgY2hpY2tzIGZlZCBvbiBob3JzZWJlYW4sIG9yZGVyZWQgYWxvbmcgaW5jcmVhc2luZyB3ZWlnaHQuIEFsc28sIG1ha2UgdGhlIGJhcnMgb2YgZGlmZmVyZW50IGNvbG9yIGFuZCBhZGp1c3QgdGhlIHNwYWNpbmcgYmV0d2VlbiBjb2x1bW5zIHRvIDAuNS48cD4KYGBge3J9CiMgeW91ciBjb2RlIGNvbWVzIGhlcmU6CmBgYAoKPGJyPjxicj4KCiMjICpDb21iaW5pbmcgZGlmZmVyZW50IHBsb3RzIHRvIHNhbWUgZmlndXJlKgo8cCBzdHlsZT0ndGV4dC1hbGlnbjoganVzdGlmeTsnPlNvbWUgdGltZXMgaXQgbWlnaHQgYmUgZGVzaXJhYmxlIHRvIHByZXNlbnQgc2V2ZXJhbCBwbG90cyBzaWRlIGJ5IHNpZGUuIFdoaWxlIHRoZXJlIGFyZSBzZXZlcmFsIGFwcHJvYWNoZXMgZm9yIGFjaGlldmluZyB0aGlzIGluIGJhc2UgKipSKiosIHdlIHdpbGwgaGVyZSB1c2UgdGhlIHNpbXBsZXMgYWx0ZXJuYXRpdmUuIFRoaXMgaXMgZG9uZSBieSBhbHRlcmluZyBmaWd1cmUgcGFyYW1ldGVyczo8cD4KYGBge3J9CiMgUGxvdCB0d28gZmlndXJlcyBiZXNpZGUgZWFjaCBvdGhlcjoKcGFyKG1mcm93ID0gYygxLDIpKSAjIGNoYW5nZSBmaWd1cmUgcGFyYW1ldGVycwoKIyBsZWZ0IHBsb3Q6CnBsb3QoYWlycXVhbGl0eSRTb2xhci5SLGFpcnF1YWxpdHkkT3pvbmUsCiAgICAgeGxhYj0nU29sYXIgcmFkaWF0aW9uJyx5bGFiPSdPem9uZSAocHBiKScsCiAgICAgcGNoPTIxLGJnPSdkb2RnZXJibHVlJyxtYWluPSdTY2F0dGVycGxvdCcpCgojIHJpZ2h0IHBsb3Q6Cmhpc3QoYWlycXVhbGl0eSRUZW1wLAogICAgIG1haW49J0hpc3RvZ3JhbScseGxhYj0nVGVtcGVyYXR1cmUgKMKwRiknLGNvbD0nd2hlYXQnKQpgYGAKCi0tLQoKPGJyPjxicj4KCiMgVmlzdWFsaXNpbmcgd2l0aCBnZ3Bsb3QKRXNwZWNpYWxseSBpZiB5b3VyIG5vdCBpbnRvIGVsYWJvcmF0ZSBwcm9ncmFtbWluZyBvZiBncmFwaGljYWwgbGF5b3V0LCBhIGdvb2Qgb3B0aW9uIGlzIHRvIHR1cm4gdG8gYGdncGxvdGAuIFdpdGggYGdncGxvdGAsIG9uZSBjYW4gbWFrZSBmYWlybHkgZ29vZCBsb29raW5nIGdyYXBocyB3aXRoIG1pbmltYWwgZWZmb3J0LgoKYGBge3IsIHdhcm5pbmc9RiwgbWVzc2FnZT1GQUxTRX0KIyBMb2FkIGdncGxvdDoKcmVxdWlyZShnZ3Bsb3QyKQoKIyBHZXQgZXhhbXBsZSBkYXRhOgpkYXRhKE9yYW5nZSkKCiMgUGxvdDoKcCA9IGdncGxvdChPcmFuZ2UsIGFlcyhhZ2UsY2lyY3VtZmVyZW5jZSkpICsgCiAgICAgIGdlb21faml0dGVyKCkKcApgYGAKClNvIGZhciBzbyBnb29kLiBIb3dldmVyLCB0aGUgcGxvdCBkb2VzIG5vdCBsb29rIHRvbyBpbXByZXNzaXZlLgpBcyB3ZSBoYXZlIHNhdmVlZCB0aGUgcGxvdCB0byBvYmplY3QgYHBgLCB3ZSBjYW4gY29udGludWUgYWRkaW5nIG5ldyBsYXllcnMgdG8gdGhhdCBvYmplY3QsIGp1c3QgbGlrZSBpbiBhIGdyYXBoaWNhbCBlZGl0b3I6CmBgYHtyLG1lc3NhZ2U9Rix3YXJuaW5nPUZBTFNFfQpwICsgZ2VvbV9zbW9vdGgoKSArIHRoZW1lX21pbmltYWwoKQpgYGAKVGhpcyBsb29rcyBtdWNoIGJldHRlciBhbHJlYWR5LgoKV2UgY291bGQgYWxzbyBhZGQgc29tZSBleWUtY2FuZHkgYWNjb3JkaW5nIHRvIGEgZ3JvdXBpbmcgZmFjdG9yIGluIHRoZSBkYXRhOgpgYGB7cixtZXNzYWdlPUZBTFNFfQpwID0gZ2dwbG90KE9yYW5nZSwgYWVzKGFnZSxjaXJjdW1mZXJlbmNlLGNvbD1UcmVlKSkgKyAKICAgICAgZ2VvbV9qaXR0ZXIoKSArIAogICAgICBnZW9tX3Ntb290aChzZT1GKSArCiAgICAgIHRoZW1lX21pbmltYWwoKSArCiAgICAgIHhsYWIoJ1RyZWUgYWdlIChkYXlzKScpICsgCiAgICAgIHlsYWIoJ0NpcmN1bWZlbnJlbmNlIGF0IGNoZXN0IGhpZ2h0IChtbSknKQpwCmBgYAoKLSAqKkRvIGl0IHlvdXJzZWxmISoqIE1ha2UgYSBob3Jpem9udGFsIGJveHBsb3Qgb2YgY2hpY2sgd2VpZ2h0IGFjY29yZGluZyB0byBmZWVkIGluIGdncGxvdC4gTWFrZSBzb3JlIHRoYXQgdGhlIGJveGVzIGFyZSBmaWxsZWQgd2l0aCBkaWZmZXJlbnQgY29sb3IgZGVwZW5kaW5nIG9uIGZlZWQgdHlwZS4KYGBge3J9CiMgeW91ciBjb2RlIGNvbWVzIGhlcmU6CmBgYAoKIyBVc2luZyBQbG90bHkKPHAgc3R5bGU9J3RleHQtYWxpZ246IGp1c3RpZnk7Jz5XaGlsZSBgZ2dwbG90YCBpcyBncmVhdCwgaXQgZ2VuZXJhdGVzIHN0YXRpYyBncmFwaHMsIGp1c3QgbGlrZSBiYXNlLSoqUioqLiBJZiBvbmUgZGVzaXJlcyB0byBhZGQgaW50ZXJhY3RpdmUgY29tcG9uZW50cyB0byBmaWd1cmVzLCBvbmUgY2FuIHVzZSBlaXRoZXIgW2BnZ3ZpemBdKGh0dHBzOi8vZ2d2aXMucnN0dWRpby5jb20vKSAoYW4gaW1wbGVtZW50YXRpb24gb2YgYW4gaW50ZXJhY3RpdmUgZ3JhbW1hciBvZiBncmFwaGljcywgdGFraW5nIHRoZSBiZXN0IHBhcnRzIG9mIGBnZ3Bsb3RgLCBjb21iaW5pbmcgdGhlbSB3aXRoIHRoZSByZWFjdGl2ZSBmcmFtZXdvcmsgb2YgYHNoaW55YCBhbmQgZHJhd2luZyB3ZWIgZ3JhcGhpY3MgdXNpbmcgYHZlZ2FgKSBvciBbYHBsb3RseWBdKGh0dHBzOi8vcGxvdGx5LXIuY29tLyk8cD4KClRoZSBlYXNpZXN0IHdheSB0byB1c2UgYHBsb3RseWAgaXMgdG8gY29udmVydCBhbiBleGFpc3RpbmcgYGdncGxvdGAgdmlzdWFsaXNhdGlvbiB0byBgcGxvdGx5YDoKYGBge3IsbWVzc2FnZT1GQUxTRX0KbGlicmFyeShwbG90bHkpCgpnZ3Bsb3RseShwKQpgYGAKCkJ1aWxkaW5nIGBwbG90bHlgIGdyYXBocyBmcm9tIHNjcmF0Y2g6CmBgYHtyLHdhcm5pbmc9RkFMU0V9CnAyID0gcGxvdF9seShtdGNhcnMsIHggPSB+ZGlzcCwgeSA9IH5tcGcpCnAyID0gYWRkX21hcmtlcnMocDIsIGNvbG9yID0gfmZhY3RvcihjeWwpLCBzaXplID0gfmdlYXIpCnAyCmBgYAoK